import {vec3} from "gl-matrix";


export class Box3 {
    constructor(public min: vec3 = vec3.fromValues(
        Infinity, Infinity, Infinity
    ), public max: vec3 = vec3.fromValues(
        -Infinity, -Infinity, -Infinity
    )) {

    }

    makeEmpty() {
        this.min[0] = this.min[1] = this.min[2] = Infinity;
        this.max[0] = this.max[1] = this.max[2] = -Infinity;
        return this;
    }

    isEmpty() {
        return (this.min[0] > this.max[0]) || (this.min[1] > this.max[1]) || (this.min[2] > this.max[2])
    }

    addPoint(point: vec3) {

        // x
        if (point[0] < this.min[0]) {
            this.min[0] = point[0]
        } else if (point[0] > this.max[0]) {
            this.max[0] = point[0]
        }

        // y
        if (point[1] < this.min[1]) {
            this.min[1] = point[1]
        } else if (point[1] > this.max[1]) {
            this.max[1] = point[1]
        }

        // z
        if (point[2] < this.min[2]) {
            this.min[2] = point[2]
        } else if (point[2] > this.max[2]) {
            this.max[2] = point[2]
        }
    }

    setFromPoints(lst: Array<vec3>) {
        if (lst.length > 0) {
            let point = lst[0];
            vec3.set(this.min, point[0], point[1], point[2]);
            vec3.set(this.max, point[0], point[1], point[2]);
            for (let i = 1, ilen = lst.length; i < ilen; ++i) {
                this.addPoint(lst[i]);
            }
        } else {
            this.makeEmpty();
        }
    }

    containsPoint(point: vec3) {
        if (point[0] < this.min[0] || point[0] > this.max[0] ||
            point[1] < this.min[1] || point[1] > this.max[1] ||
            point[2] < this.min[2] || point[2] > this.max[2]) {
            return false;
        }
        return true;
    }

    containsBox(box: Box3) {
        if ((this.min[0] <= box.min[0]) && (box.max[0] <= this.max[0]) &&
            (this.min[1] <= box.min[1]) && (box.max[1] <= this.max[1]) &&
            (this.min[2] <= box.min[2]) && (box.max[2] <= this.max[2])) {
            return true;
        }
        return false;
    }
}
